#include "Importer.h"

/*-----------------------------------------------------------------------------------------------*/
bool Importer::importSprite(XMLNode& spriteNode)
{
   std::map<std::string, Sprite*>::iterator it;
   
   const char* spriteName = spriteNode.getAttribute("Name");
   Sprite* pSprite = NULL;

   //search for the given sprite on the sprite-map
   for ( it =  m_spriteMap.begin(); it != m_spriteMap.end(); ++it )
   {
      if (it->first.c_str() == spriteName)
      {
         pSprite = it->second;
         return true;
      }
   }

   //if we don't have the sprite on the sprite-map
   pSprite = new Sprite(spriteName);

   m_pCurrentSprite = pSprite;
   
   m_spriteMap[spriteName] = pSprite;

   UINT positionX = atoi( spriteNode.getAttribute("X") );
   UINT positionY = atoi( spriteNode.getAttribute("Y") );
   UINT width  = atoi( spriteNode.getAttribute("width") );
   UINT height = atoi( spriteNode.getAttribute("height") );

   const char* textureXMLFilePath = spriteNode.getAttribute("TextureXMLFile");
   XMLNode mainNode = XMLNode::openFileHelper(textureXMLFilePath);
   XMLNode& textureNode = mainNode.getChildNode("Texture");
   importTexture(textureNode);

   const char* textureFile = textureNode.getAttribute("FilePath");
   
   pSprite->setTexture( m_pTextureMap[textureFile] );

   pSprite->setName(spriteName);
   
   if ( !pSprite->setTextureArea(positionX, positionY, width, height) )
   {
      std::cout << "Failed on Sprite->SetTextureArea for texture" << textureFile << std::endl;
      return false;
   }

   // ANIMATION
   int conut = 0;
   for (int i = 0; i < spriteNode.nChildNode("ANIMATION"); ++i)
   {
      XMLNode& animation = spriteNode.getChildNode("ANIMATION", &conut);
      if ( !importAnimation(animation) )
      {
         std::cout << "Failed on importAnimation" << std::endl;
         return false;
      }
   }

   return true;
}
/*-----------------------------------------------------------------------------------------------*/
bool Importer::importTexture(XMLNode& textureNode)
{
   const char* textureFilePath = textureNode.getAttribute("FilePath");
   Texture::TexturePtr pTexture;

   std::map<std::string, Texture::TexturePtr>::iterator it;

   //look for the texture in the texture map
   for ( it = m_pTextureMap.begin(); it != m_pTextureMap.end(); ++it )
   {
      if( it->first.c_str() == textureFilePath )
      {
         pTexture = it->second;
         return true;
      }
   }

   XMLNode colorKeyNode = textureNode.getChildNode("ColorKey");

   ColorKey colorKey;

   colorKey.red   = atoi( colorKeyNode.getAttribute("R") );
   colorKey.green = atoi( colorKeyNode.getAttribute("G") );
   colorKey.blue  = atoi( colorKeyNode.getAttribute("B") );

   pTexture = Texture::TexturePtr( new Texture(textureFilePath, colorKey) );

   m_pTextureMap[textureFilePath] = pTexture;

   if ( !m_pRenderer->loadTexture(textureFilePath, pTexture) )
   {
      std::cout << "Filed to import texture: " << textureFilePath << std::endl;
   }

   return true;
}
/*-----------------------------------------------------------------------------------------------*/
bool Importer::importResources(const char* xmlTextureFileName)
{
   XMLNode xmlMainNode = XMLNode::openFileHelper(xmlTextureFileName, "SPRITES");

   int cont = 0;
   for(int i=0; i < xmlMainNode.nChildNode("SPRITE"); ++i)
   {
      XMLNode& sprite = xmlMainNode.getChildNode("SPRITE", &cont);
      if ( !importSprite(sprite) )
      {
         std::cout << "Failed to import xmlFile: " << xmlTextureFileName << std::endl;
         return false;
      }
   }

   return true;
}
/*-----------------------------------------------------------------------------------------------*/
bool Importer::createSprite(const char* name, Sprite* sprite)
{
   Sprite* sprite2 = m_spriteMap[name];

   if(!sprite2)
   {
      return false;
   }

   sprite2->clone(sprite);

   return true;
}
/*-----------------------------------------------------------------------------------------------*/
bool Importer::importAnimation(XMLNode& animationNode)
{
   const char* animationName = animationNode.getAttribute("Name");
   
   std::map<std::string, AnimationInfo::AnimationInfoPtr>::iterator it;

   AnimationInfo::AnimationInfoPtr pAnimationInfo;
   
   if ( m_animationMap.count(animationName) )
   {
      return true;
   }

   //if the animation is not inside the map
   pAnimationInfo = AnimationInfo::AnimationInfoPtr( new AnimationInfo() );
   
   const char* time = animationNode.getAttribute("Time"); 
   pAnimationInfo->setLength(atof(time));

   const char* pSpeed = animationNode.getAttribute("Speed");
   pAnimationInfo->setSpeed( atof(pSpeed) );

   const std::string pLoop = animationNode.getAttribute("Loop");
   pAnimationInfo->setLoopable(pLoop == "true");

   int conut = 0;
   for(int i = 0; i < animationNode.nChildNode("FRAME"); ++i)
   {
      XMLNode& frame = animationNode.getChildNode("FRAME", &conut);

      unsigned int X = atoi( frame.getAttribute("X") );
      unsigned int Y = atoi( frame.getAttribute("Y") );

      unsigned int width  = atoi( frame.getAttribute("width") );
      unsigned int height = atoi( frame.getAttribute("height") );

      pAnimationInfo->addFrame(X, Y, width, height);
   }

   if ( !m_pCurrentSprite->addAnimationInfo(animationName, pAnimationInfo) )
   {
      std::cout << "addAdnimationInfo failed with " << animationName << std::endl;; 
      return false;
   }

   m_animationMap[animationName] = pAnimationInfo;

   return true;
}